using UnityEngine;

[ExecuteInEditMode]
public class ScreenAnchor : MonoBehaviour
{
	public new Camera camera;

	public HAlign H_align;

	public float H_offset;

	public OffsetUnits H_units;

	public VAlign V_align;

	public float V_offset;

	public OffsetUnits V_units;

	public bool doUpdate = true;

	private Renderer sprite;

	private float spriteScreenWidth;

	private float spriteScreenHeight;

	public BoxCollider referenceCollider;

	private Plane projPlane;

	private bool firstUpdate = true;

	private void Start()
	{
		sprite = GetComponent<Renderer>();
	}

	private void Update()
	{
		if (!(camera == null) && (doUpdate || firstUpdate || Application.isEditor))
		{
			if (referenceCollider != null)
			{
				referenceCollider.enabled = true;
				projPlane = new Plane(Vector3.back, referenceCollider.transform.position);
			}
			else
			{
				projPlane = new Plane(Vector3.back, sprite.transform.position);
			}
			UpdateScreenSize();
			UpdatePosition();
			doUpdate = false;
			firstUpdate = false;
			if (referenceCollider != null)
			{
				referenceCollider.enabled = false;
			}
		}
	}

	private void UpdatePosition()
	{
		base.transform.position = GetSpritePosition(H_align, H_units, H_offset, V_align, V_units, V_offset);
	}

	public void UpdateScreenSize()
	{
		Bounds spriteBounds = GetSpriteBounds();
		spriteScreenWidth = Vector3.Distance(camera.WorldToScreenPoint(spriteBounds.center + Vector3.left * spriteBounds.extents.x), camera.WorldToScreenPoint(spriteBounds.center + Vector3.right * spriteBounds.extents.x));
		spriteScreenHeight = Vector3.Distance(camera.WorldToScreenPoint(spriteBounds.center + Vector3.up * spriteBounds.extents.y), camera.WorldToScreenPoint(spriteBounds.center + Vector3.down * spriteBounds.extents.y));
	}

	private Bounds GetSpriteBounds()
	{
		if (referenceCollider != null)
		{
			return referenceCollider.bounds;
		}
		return sprite.bounds;
	}

	private float WorldToScreenSize(float size)
	{
		return Vector3.Distance(camera.WorldToScreenPoint(Vector3.zero), camera.WorldToScreenPoint(Vector3.right * size));
	}

	private float ScreenToWorldSize(float size)
	{
		Ray ray = camera.ScreenPointToRay(Vector3.zero);
		float enter;
		projPlane.Raycast(ray, out enter);
		Vector3 point = ray.GetPoint(enter);
		ray = camera.ScreenPointToRay(Vector3.right * size);
		projPlane.Raycast(ray, out enter);
		Vector3 point2 = ray.GetPoint(enter);
		return Vector3.Distance(point, point2);
	}

	public Vector3 GetSpritePosition(HAlign h_align, OffsetUnits h_units, float h_offset, VAlign v_align, OffsetUnits v_units, float v_offset)
	{
		float num = 0f;
		float num2 = 0f;
		float num3 = h_offset;
		switch (h_units)
		{
		case OffsetUnits.ScreenUnits:
			num3 *= (float)Screen.width;
			break;
		case OffsetUnits.SpriteUnits:
			num3 *= spriteScreenWidth;
			break;
		}
		num = (float)((int)h_align * Screen.width) / 2f + num3;
		num3 = v_offset;
		switch (v_units)
		{
		case OffsetUnits.ScreenUnits:
			num3 *= (float)Screen.height;
			break;
		case OffsetUnits.SpriteUnits:
			num3 *= spriteScreenHeight;
			break;
		}
		num2 = (float)((int)v_align * Screen.height) / 2f + num3;
		Ray ray = camera.ScreenPointToRay(new Vector3(num, num2, 0f));
		float enter;
		projPlane.Raycast(ray, out enter);
		return ray.GetPoint(enter);
	}
}
